package com.xpqh.ksg.config.properties;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 数据库数据源配置
 * </p>
 * <p>
 * 说明:这个类中包含了许多默认配置,若这些配置符合您的情况,您可以不用管,若不符合,建议不要修改本类,建议直接在"application.yml"中配置即可
 * </p>
 * 
 * @author lizhihui
 * @date 2025.03.21
 */
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidProperties {

	private String url;

	private String username;

	private String password;

	// private String driverClassName = "com.mysql.cj.jdbc.Driver";
	private String driverClassName;

	private Integer initialSize = 2;

	private Integer minIdle = 1;

	private Integer maxActive = 32;

	private Integer maxWait = 60000;

	private Integer timeBetweenEvictionRunsMillis = 60000;

	private Integer minEvictableIdleTimeMillis = 30000;

	private String validationQuery = "SELECT 'x'";

	private Boolean testWhileIdle = true;

	private Boolean testOnBorrow = false;

	private Boolean testOnReturn = false;

	private Boolean poolPreparedStatements = false;

	private Integer maxPoolPreparedStatementPerConnectionSize = 20;

	private String filters;

	@Bean
	public DataSource config() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);

		dataSource.setDriverClassName(driverClassName);
		dataSource.setInitialSize(initialSize); // 定义初始连接数
		dataSource.setMinIdle(minIdle); // 最小空闲
		dataSource.setMaxActive(maxActive); // 定义最大连接数
		dataSource.setMaxWait(maxWait); // 最长等待时间

		// 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
		dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

		// 配置一个连接在池中最小生存的时间，单位是毫秒
		dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
		dataSource.setValidationQuery(validationQuery);
		dataSource.setTestWhileIdle(testWhileIdle);
		dataSource.setTestOnBorrow(testOnBorrow);
		dataSource.setTestOnReturn(testOnReturn);
		// 打开PSCache，并且指定每个连接上PSCache的大小
		dataSource.setPoolPreparedStatements(poolPreparedStatements);
		dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
		List<Filter> proxyFilters = new ArrayList<Filter>();
		WallFilter statFilter = new WallFilter();
		WallConfig config = new WallConfig();
		config.setMultiStatementAllow(true); // 批量操作
		config.setNoneBaseStatementAllow(true);//允许非基本语句的其他语句
		statFilter.setConfig(config);
		proxyFilters.add(statFilter);
		dataSource.setProxyFilters(proxyFilters);
		try {
			dataSource.setFilters(filters);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return dataSource;
	}
}
